import React, { createElement, ForwardedRef, forwardRef, useRef } from 'react'

import LxfDrawer from '../lxf-drawer'
import LxfModal from '../lxf-modal';
import { useFloatWrapper } from './hooks'
import {
  IFloatWrappedComponentRef,
  IFloatWrappedDrawerProps,
  IFloatWrappedModalProps,
  IFloatWrapperRef,
  IWithFloatWrapperOptions,
} from './types'

export * from './hooks';
export * from './types';

/**
 * 弹窗浮层容器
 * @param options 浮层配置
 * @returns
 */
function withModal<P = {}>(options?: IWithFloatWrapperOptions<P>) {
  const { defaultProps } = options ?? {};

  return function (Component: any) {
    const ForwardedCompoent = forwardRef<IFloatWrappedComponentRef, any>(
      Component,
    );

    const WrappedComponent = (
      props: IFloatWrappedModalProps<P>,
      ref: ForwardedRef<IFloatWrapperRef<P>>,
    ) => {
      const wrapperProps = {
        ...defaultProps,
        ...props,
      };
      const wrappedComponentRef = useRef<IFloatWrappedComponentRef>(null);

      const [{ visible, title, componentProps }, { onOk, onCancel }] =
        useFloatWrapper<P>(ref, wrapperProps, wrappedComponentRef);

      return (
        <LxfModal
          {...wrapperProps}
          visible={visible}
          title={title}
          onOk={onOk}
          onCancel={onCancel}
        >
          {createElement(ForwardedCompoent, {
            ref: wrappedComponentRef,
            visible,
            title,
            onOk,
            onCancel,
            ...componentProps,
          })}
        </LxfModal>
      );
    };

    const ForwardedComponent = forwardRef<
      IFloatWrapperRef<P>,
      IFloatWrappedModalProps<P>
    >(WrappedComponent);

    return ForwardedComponent;
  };
}
/**
 * 抽屉浮层容器
 * @param options 浮层配置
 * @returns
 */
function withDrawer<P = {}>(options?: IWithFloatWrapperOptions<P>) {
  const { defaultProps } = options ?? {};

  return function (Component: any) {
    const ForwardedCompoent = forwardRef<IFloatWrappedComponentRef, any>(
      Component,
    );

    const WrappedComponent = (
      props: IFloatWrappedDrawerProps<P>,
      ref: ForwardedRef<IFloatWrapperRef<P>>,
    ) => {
      const wrapperProps = {
        ...defaultProps,
        ...props,
      };
      const wrappedComponentRef = useRef<IFloatWrappedComponentRef>(null);

      const [{ visible, title, componentProps }, { onOk, onCancel }] =
        useFloatWrapper<P>(ref, wrapperProps, wrappedComponentRef);

      return (
        <LxfDrawer
          {...wrapperProps}
          visible={visible}
          title={title}
          onOk={onOk}
          onCancel={onCancel}
        >
          {createElement(ForwardedCompoent, {
            ref: wrappedComponentRef,
            visible,
            title,
            onOk,
            onCancel,
            ...componentProps,
          })}
        </LxfDrawer>
      );
    };

    const ForwardedComponent = forwardRef<
      IFloatWrapperRef<P>,
      IFloatWrappedDrawerProps<P>
    >(WrappedComponent);

    return ForwardedComponent;
  };
}


/** 浮层容器 */
const LxfFloatWrapper = {
  /** 抽屉类型 */
  withDrawer,
  /** 弹窗类型 */
  withModal,
};

export default LxfFloatWrapper;